<!doctype html>
<html lang="zh"><head><meta charset="utf-8"><meta name="generator" content="Hexo 4.2.0"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><meta><meta name="keywords" content="[object Object]"><meta name="description" content="基于上一个node极简评论系统做的一个具有增删改的小型学生管理系统,这次使用到了Express，使用js的模块化编程将路由和增删改操作分别抽离成模块再使用。


        这次使用到的知识点有：
        express
        body-parser
        art-template


总结：这个demo里面涉及到了回调函数，其实在之前的vue项目中使用axios请求服务器数据，处理服务器返回的数据也是回调函数，当时只是知道是回调函数，不知道或者不理解到底是什么；这个项目多次使用到了封装的回调函数，让自己对这个有了初步的理解；这个项目中也有针对增、删、改的操作而封装的模块，也让自己对模块有了更深的理解。
还存在的问题：虽然封装了增、删、改的操作，减少了代码的重复率，但是封装不彻底，仍有部分代码是重复的，后续熟练使用回调函数的时候再进行进一步优化。"><meta name="author" content="uncledwyane"><title>Node 学生管理系统（Express + 读写JSON文件） - Wb&#039;s blog</title><meta description="基于上一个node极简评论系统做的一个具有增删改的小型学生管理系统,这次使用到了Express，使用js的模块化编程将路由和增删改操作分别抽离成模块再使用。           这次使用到的知识点有：         express         body-parser         art-template   总结：这个demo里面涉及到了回调函数，其实在之前的vue项目中使用a"><meta property="og:type" content="article"><meta property="og:title" content="Node 学生管理系统（Express + 读写JSON文件）"><meta property="og:url" content="https://hywb.xyz/2020/05/20/node-studentOS-file/"><meta property="og:site_name" content="Wb&#039;s blog"><meta property="og:description" content="基于上一个node极简评论系统做的一个具有增删改的小型学生管理系统,这次使用到了Express，使用js的模块化编程将路由和增删改操作分别抽离成模块再使用。           这次使用到的知识点有：         express         body-parser         art-template   总结：这个demo里面涉及到了回调函数，其实在之前的vue项目中使用a"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/avatar.png"><meta property="article:published_time" content="2020-05-20T13:02:29.000Z"><meta property="article:modified_time" content="2020-05-24T14:15:47.169Z"><meta property="article:author" content="uncledwyane"><meta property="article:tag" content="node"><meta property="twitter:card" content="summary"><meta property="twitter:image" content="https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/avatar.png"><script type="application/ld+json">{"@context":"https://schema.org","@type":"BlogPosting","mainEntityOfPage":{"@type":"WebPage","@id":"https://hywb.xyz/2020/05/20/node-studentOS-file/"},"headline":"Node 学生管理系统（Express + 读写JSON文件）","image":["http://localhost:4000/img/avatar.png"],"datePublished":"2020-05-20T13:02:29.000Z","dateModified":"2020-05-24T14:15:47.169Z","author":{"@type":"Person","name":"uncledwyane"},"description":"基于上一个node极简评论系统做的一个具有增删改的小型学生管理系统,这次使用到了Express，使用js的模块化编程将路由和增删改操作分别抽离成模块再使用。           这次使用到的知识点有：         express         body-parser         art-template   总结：这个demo里面涉及到了回调函数，其实在之前的vue项目中使用a"}</script><link rel="icon" href="https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/logo.png"><link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/font-awesome/5.12.0/css/all.min.css"><link rel="stylesheet" href="https://fonts.loli.net/css?family=Ubuntu:400,600|Source+Code+Pro|Monda:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&amp;amp;subset=latin,latin-ext|Inconsolata|Itim|Lobster.css"><link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css"><style>body>.footer,body>.navbar,body>.section{opacity:0}</style><!--!--><!--!--><link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/lightgallery/1.6.12/css/lightgallery.min.css"><link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/justifiedGallery/3.7.0/css/justifiedGallery.min.css"><!--!--><!--!--><script src="https://cdnjs.loli.net/ajax/libs/pace/1.0.2/pace.min.js"></script><link rel="stylesheet" href="/css/style.css"><script src="https://cdnjs.loli.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script src="/js/globalUtils.js"></script><script async="" referrerpolicy="no-referrer" src="//cdn.jsdelivr.net/npm/leancloud-storage@3/dist/av-min.js"></script><script src="//unpkg.com/valine/dist/Valine.min.js"></script><script src="/js/md5.min.js"></script></head><body class="is-3-column has-navbar-fixed-top"><nav class="navbar navbar-main is-fixed-top"><div class="container"><div class="navbar-brand justify-content-center"><a class="navbar-item navbar-logo" href="/"><img src="https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/logo.png" alt="Wb&#039;s blog" height="28"></a></div><div class="navbar-menu"><div class="navbar-start"><a class="navbar-item" href="/">首页</a><a class="navbar-item" href="/archives">归档</a><a class="navbar-item" href="/categories">分类</a><a class="navbar-item" href="/tags">标签</a><a class="navbar-item" href="/about">关于</a></div><div class="navbar-end"><a class="navbar-item" target="_blank" rel="noopener" title="Download on GitHub" href="https://github.com/uncledwyane"><i class="fab fa-github"></i></a><a class="navbar-item search" title="搜索" href="javascript:;"><i class="fas fa-search"></i></a><a class="navbar-item" id="night-nav" title="Night Mode" href="javascript:;"><i class="fas fa-moon" id="night-icon"></i></a></div></div></div></nav><script type="text/javascript" src="/js/theme-setting.js"></script><section class="section"><div class="container"><div class="columns"><div class="column order-2 column-main is-8-tablet is-8-desktop is-9-widescreen"><div class="card"><article class="card-content article" role="article"><div class="article-meta size-small is-uppercase level is-mobile"><div class="level-left"><i class="far fa-calendar-plus"> </i>2020-05-20  <a class="commentCountImg" href="/2020/05/20/node-studentOS-file/#comment-container"><span class="display-none-class">/2020/05/20/node-studentOS-file/</span><i class="far fa-comment-dots"></i> <span class="commentCount" id="85bbaeb47a2c4b39dae2ff57a0dd184b">99+</span>  </a><span class="level-item"><i class="far fa-clock"> </i>8 分钟  <i class="fas fa-pencil-alt"> </i>1.2 k</span></div></div><h1 class="title is-3 is-size-4-mobile">Node 学生管理系统（Express + 读写JSON文件）</h1><div class="content"><div class='notification is-primary post-summary'>
    <p>基于上一个node极简评论系统做的一个具有增删改的小型学生管理系统,这次使用到了Express，使用js的模块化编程将路由和增删改操作分别抽离成模块再使用。</p>
</div>
<ul class='post-summary'>
        <li>这次使用到的知识点有：</li>
        <li>express</li>
        <li>body-parser</li>
        <li>art-template</li>
</ul>

<p>总结：这个demo里面涉及到了回调函数，其实在之前的vue项目中使用axios请求服务器数据，处理服务器返回的数据也是回调函数，当时只是知道是回调函数，不知道或者不理解到底是什么；这个项目多次使用到了封装的回调函数，让自己对这个有了初步的理解；这个项目中也有针对增、删、改的操作而封装的模块，也让自己对模块有了更深的理解。</p>
<p>还存在的问题：虽然封装了增、删、改的操作，减少了代码的重复率，但是封装不彻底，仍有部分代码是重复的，后续熟练使用回调函数的时候再进行进一步优化。</p>
<a id="more"></a>

<div align='center'>
    <img src='https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/crud.gif' alt='效果图'/>
    <br>
    <img src='https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/trees.jpg' alt='项目结构'/>
</div>


<h3 id="路由模块-router-js"><a href="#路由模块-router-js" class="headerlink" title="路由模块 router.js"></a>路由模块 router.js</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> express = <span class="built_in">require</span>(<span class="string">'express'</span>)</span><br><span class="line"><span class="keyword">const</span> router = express()</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"><span class="keyword">const</span> Action = <span class="built_in">require</span>(<span class="string">'./action'</span>)</span><br><span class="line"></span><br><span class="line">router.get(<span class="string">'/students'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    fs.readFile(<span class="string">'./students.json'</span>, (err, data) =&gt; &#123;</span><br><span class="line">        <span class="keyword">let</span> students = <span class="built_in">JSON</span>.parse(data).students</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">this</span>.response.status(<span class="number">500</span>).send(<span class="string">'oops! Something Crashed!!!'</span>)</span><br><span class="line">        </span><br><span class="line">        res.render(<span class="string">'index.html'</span>, &#123;</span><br><span class="line">            students: students</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">router.get(<span class="string">'/students/new'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    res.render(<span class="string">'add_student.html'</span>)</span><br><span class="line">&#125;)</span><br><span class="line">    </span><br><span class="line">router.post(<span class="string">'/students/new'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    <span class="comment">// 使用 body-parser 获取的请求数据给student</span></span><br><span class="line">    <span class="keyword">let</span> student = req.body</span><br><span class="line">    <span class="comment">// 使用封装的保存学生的 save 方法，两个参数，一个是学生实参，一个为错误，错误用用回调函数处理</span></span><br><span class="line">    Action.save(student, (err) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            res.status(<span class="number">500</span>).send(<span class="string">'Error'</span>)</span><br><span class="line">        <span class="comment">// 重定向到首页</span></span><br><span class="line">        res.redirect(<span class="string">'/students'</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">router.get(<span class="string">'/students/edit'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    <span class="keyword">let</span> reqId = <span class="built_in">parseInt</span>(req.query.id)</span><br><span class="line">    Action.findById(reqId, (err, student) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> res.status(<span class="number">500</span>).send(<span class="string">'Oops! Something Error'</span>)</span><br><span class="line">        res.render(<span class="string">'edit_student.html'</span>, &#123;</span><br><span class="line">            student: student</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">router.post(<span class="string">'/students/edit'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    <span class="keyword">let</span> student = req.body</span><br><span class="line">    Action.editById(student, (err) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> res.status(<span class="number">500</span>).send(<span class="string">'Oops! Something Error'</span>)</span><br><span class="line">        res.redirect(<span class="string">'/students'</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">router.get(<span class="string">'/students/delete'</span>, (req, res) =&gt; &#123;</span><br><span class="line">    <span class="keyword">let</span> id = <span class="built_in">parseInt</span>(req.query.id)</span><br><span class="line">    Action.deleteById(id, (err) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> res.status(<span class="number">500</span>).send(<span class="string">'Oops! Something Error'</span>)</span><br><span class="line">        res.redirect(<span class="string">'/students'</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">module</span>.exports = router</span><br></pre></td></tr></table></figure>

<h3 id="读写文件模块-action-js"><a href="#读写文件模块-action-js" class="headerlink" title="读写文件模块 action.js"></a>读写文件模块 action.js</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"><span class="keyword">const</span> db_url = <span class="string">'./students.json'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 保存添加学生数据到json文件里</span></span><br><span class="line"><span class="comment"> * 封装save方法，使用回调函数处理错误</span></span><br><span class="line"><span class="comment"> * 两个参数 student为传入的新增学生对象</span></span><br><span class="line"><span class="comment"> * callback为回调函数，处理错误</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">exports.save = <span class="function">(<span class="params">student,callback</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">// 读取文件内容</span></span><br><span class="line">    fs.readFile(db_url, <span class="string">'utf8'</span>, (err, data) =&gt; &#123;</span><br><span class="line">        <span class="comment">// 如果有错误，使用回调函数处理     </span></span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> callback(err)</span><br><span class="line">        <span class="comment">// 没有错误就把获取的数据转换成字符串并赋值给students</span></span><br><span class="line">        <span class="keyword">let</span> students = <span class="built_in">JSON</span>.parse(data).students</span><br><span class="line">        <span class="keyword">if</span>(students.length === <span class="number">0</span>)&#123;</span><br><span class="line">            student.id = <span class="number">1</span></span><br><span class="line">            students.push(student)</span><br><span class="line">            <span class="keyword">let</span> newStudents = <span class="built_in">JSON</span>.stringify(&#123;</span><br><span class="line">                students: students</span><br><span class="line">            &#125;)</span><br><span class="line">            <span class="comment">// 写入文件，如果有错，就是用回调函数处理</span></span><br><span class="line">            fs.writeFile(db_url, newStudents, (err) =&gt; &#123;</span><br><span class="line">                <span class="comment">// 如果有错误，使用回调函数处理</span></span><br><span class="line">                <span class="keyword">if</span>(err)</span><br><span class="line">                    <span class="keyword">return</span> callback(err)</span><br><span class="line">                <span class="comment">// 没有错误，使回调函数参数为空</span></span><br><span class="line">                callback(<span class="literal">null</span>)</span><br><span class="line">            &#125;)</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 添加 id </span></span><br><span class="line">        student.id = students[students.length - <span class="number">1</span>].id + <span class="number">1</span></span><br><span class="line">        <span class="comment">// 将新增的学生添加到从文件获取的数据中</span></span><br><span class="line">        students.push(student)</span><br><span class="line">        <span class="comment">// 将 包含新增学生的数据格式化为JSON格式，并传递给newStudents</span></span><br><span class="line">        <span class="keyword">let</span> newStudents = <span class="built_in">JSON</span>.stringify(&#123;</span><br><span class="line">            students: students</span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="comment">// 写入文件，如果有错，就是用回调函数处理</span></span><br><span class="line">        fs.writeFile(db_url, newStudents, (err) =&gt; &#123;</span><br><span class="line">            <span class="comment">// 如果有错误，使用回调函数处理</span></span><br><span class="line">            <span class="keyword">if</span>(err)</span><br><span class="line">                <span class="keyword">return</span> callback(err)</span><br><span class="line">            <span class="comment">// 没有错误，使回调函数参数为空</span></span><br><span class="line">            callback(<span class="literal">null</span>)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 保存编辑学生方法</span></span><br><span class="line"><span class="comment"> * 使用 学生id 为关键字进行编辑</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line">exports.editById = <span class="function">(<span class="params">student, callback</span>) =&gt;</span> &#123;</span><br><span class="line">    fs.readFile(<span class="string">'./students.json'</span>, (err, data) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err) </span><br><span class="line">            <span class="keyword">return</span> callback(err)</span><br><span class="line">        <span class="keyword">let</span> students = <span class="built_in">JSON</span>.parse(data).students</span><br><span class="line"></span><br><span class="line">        student.id = <span class="built_in">parseInt</span>(student.id)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">let</span> stu = students.find(<span class="function">(<span class="params">item</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> item.id === student.id</span><br><span class="line">        &#125;)</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">let</span> key <span class="keyword">in</span> student)&#123;</span><br><span class="line">            stu[key] = student[key]</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 将 包含新增学生的数据格式化为JSON格式，并传递给newStudents</span></span><br><span class="line">        <span class="keyword">let</span> newStudents = <span class="built_in">JSON</span>.stringify(&#123;</span><br><span class="line">            students: students</span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="comment">// 写入文件，如果有错，就是用回调函数处理</span></span><br><span class="line">        fs.writeFile(db_url, newStudents, (err) =&gt; &#123;</span><br><span class="line">            <span class="comment">// 如果有错误，使用回调函数处理</span></span><br><span class="line">            <span class="keyword">if</span>(err)</span><br><span class="line">                <span class="keyword">return</span> callback(err)</span><br><span class="line">            <span class="comment">// 没有错误，使回调函数参数为空</span></span><br><span class="line">            callback(<span class="literal">null</span>)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据 id 查询学生信息</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">exports.findById = <span class="function">(<span class="params">id, callback</span>) =&gt;</span> &#123;</span><br><span class="line">    fs.readFile(<span class="string">'./students.json'</span>, (err, data) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err)</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">console</span>.log(<span class="string">'编辑失败'</span>);</span><br><span class="line">        <span class="keyword">let</span> students = <span class="built_in">JSON</span>.parse(data).students</span><br><span class="line">        <span class="keyword">let</span> student = students.find(<span class="function">(<span class="params">item</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> item.id === <span class="built_in">parseInt</span>(id)</span><br><span class="line">        &#125;)</span><br><span class="line">        callback(<span class="literal">null</span>, student)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 根据 id 删除</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line">exports.deleteById = <span class="function">(<span class="params">id, callback</span>) =&gt;</span> &#123;</span><br><span class="line">    fs.readFile(<span class="string">'./students.json'</span>, (err, data) =&gt; &#123;</span><br><span class="line">        <span class="keyword">if</span>(err) </span><br><span class="line">            <span class="keyword">return</span> callback(err)</span><br><span class="line">        <span class="keyword">let</span> students = <span class="built_in">JSON</span>.parse(data).students</span><br><span class="line"></span><br><span class="line">        <span class="keyword">let</span> index = students.findIndex(<span class="function">(<span class="params">item</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> item.id === id</span><br><span class="line">        &#125;)</span><br><span class="line">        </span><br><span class="line">        students.splice(index, <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 将 包含新增学生的数据格式化为JSON格式，并传递给newStudents</span></span><br><span class="line">        <span class="keyword">let</span> newStudents = <span class="built_in">JSON</span>.stringify(&#123;</span><br><span class="line">            students: students</span><br><span class="line">        &#125;)</span><br><span class="line">        <span class="comment">// 写入文件，如果有错，就是用回调函数处理</span></span><br><span class="line">        fs.writeFile(db_url, newStudents, (err) =&gt; &#123;</span><br><span class="line">            <span class="comment">// 如果有错误，使用回调函数处理</span></span><br><span class="line">            <span class="keyword">if</span>(err)</span><br><span class="line">                <span class="keyword">return</span> callback(err)</span><br><span class="line">            <span class="comment">// 没有错误，使回调函数参数为空</span></span><br><span class="line">            callback(<span class="literal">null</span>)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>




<style>
    .post-summary{
        display:none;
    }
</style>

</div><ul class="post-copyright"><li><strong>本文标题：</strong><a href="https://hywb.xyz/2020/05/20/node-studentOS-file/">Node 学生管理系统（Express + 读写JSON文件）</a></li><li><strong>本文作者：</strong><a href="https://hywb.xyz"></a></li><li><strong>本文链接：</strong><a href="https://hywb.xyz/2020/05/20/node-studentOS-file/">https://hywb.xyz/2020/05/20/node-studentOS-file/</a></li><li><strong>版权声明：</strong><span>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="external nofollow" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明出处！</span></li></ul><div><div class="recommend-post"><span class="is-size-6 has-text-grey has-mr-7"># 相关文章</span><br><span>  1.<a class="is-size-6" href="/2020/05/24/node-studentOS-mongo/" target="_blank">Node学生管理系统（使用MongoDB -&gt; mongoose）</a><br></span><span>  2.<a class="is-size-6" href="/2020/05/13/node-express-start/" target="_blank">使用Express和express-art-template来编写Node(配合nodemon)</a><br></span><span>  3.<a class="is-size-6" href="/2020/05/11/node-first_demo/" target="_blank">Node小案例 简易评论系统</a><br></span><span>  4.<a class="is-size-6" href="/2020/05/10/node-note/" target="_blank">Node笔记</a><br></span><span>  5.<a class="is-size-6" href="/2020/05/09/node-start/" target="_blank">【新坑】学习node.js</a><br></span></div></div><!--!--></article></div><div class="card"><div class="card-content"><h3 class="menu-label has-text-centered">喜欢这篇文章？打赏一下作者吧</h3><div class="buttons is-centered"><a class="button is-info donate"><span class="icon is-small"><i class="fab fa-alipay"></i></span><span>支付宝</span><span class="qrcode"><img src="/images/alipay.jpg" alt="支付宝"></span></a><a class="button is-success donate"><span class="icon is-small"><i class="fab fa-weixin"></i></span><span>微信</span><span class="qrcode"><img src="/images/wechatpay.jpg" alt="微信"></span></a></div></div></div><nav class="post-navigation mt-4 level is-mobile"><div class="level-start"><a class="article-nav-prev level level-item link-muted" href="/2020/05/24/node-studentOS-mongo/"><i class="level-item fas fa-chevron-left"></i><span class="level-item">Node学生管理系统（使用MongoDB -&gt; mongoose）</span></a></div><div class="level-end"><a class="article-nav-next level level-item link-muted" href="/2020/05/13/node-express-start/"><span class="level-item">使用Express和express-art-template来编写Node(配合nodemon)</span><i class="level-item fas fa-chevron-right"></i></a></div></nav><div class="card"><div class="card-content"><div class="title is-5">评论</div><div class="content" id="comment-container"></div><script>var valine = new Valine({
            el: '#comment-container' ,
            notify: false,
            verify: false,
            appId: 'jEO65FCCVCAiARdU3RxjtOCJ-gzGzoHsz',
            appKey: '1N2c9aedff0KFRrS6cJL6IHK',
            placeholder: '要不，咱说点啥........',
            avatar: 'mp',
            avatarForce: false,
            meta: ["nick","mail","link"],
            pageSize: 10,
            visitor: false,
            highlight: true,
            recordIP: false,
            path:'/2020/05/20/node-studentOS-file/',
            lang:'zh-CN',
            enableQQ:true,
            requiredFields:["nick","mail","link"]
        });</script></div></div></div><div class="column column-left is-4-tablet is-4-desktop is-4-widescreen  order-1 is-sticky"><!--!--><div class="card widget"><div class="card-content"><nav class="level"><div class="level-item has-text-centered flex-shrink-1"><div><figure class="image is-128x128 mx-auto mb-2"><img class="" src="/img/avatar.png" alt="Bo(...)"></figure><p class="title is-size-4 is-block line-height-inherit">Bo(...)</p><p class="is-size-6 is-block">此后如竟没有炬火，你便是我唯一的光...</p><p class="is-size-6 is-flex justify-content-center"><i class="fas fa-map-marker-alt mr-1"></i><span>重庆 南岸</span></p></div></div></nav><nav class="level is-mobile"><div class="level-item has-text-centered is-marginless"><div><p class="heading">文章</p><a href="/archives"><p class="title">52</p></a></div></div><div class="level-item has-text-centered is-marginless"><div><p class="heading">分类</p><a href="/categories"><p class="title">12</p></a></div></div><div class="level-item has-text-centered is-marginless"><div><p class="heading">标签</p><a href="/tags"><p class="title">20</p></a></div></div></nav><div class="level"><a class="level-item button is-primary is-rounded" href="https://weibo.com/5539423521/profile" target="_blank" rel="noopener">关注我</a></div><div class="level is-mobile"><a class="level-item button is-transparent is-white is-marginless" target="_blank" rel="noopener" title="Github" href="https://github.com/uncledwyane"><i class="fab fa-github"></i></a><a class="level-item button is-transparent is-white is-marginless" target="_blank" rel="noopener" title="Twitter" href="https://twitter.com/imwangbo"><i class="fab fa-twitter"></i></a><a class="level-item button is-transparent is-white is-marginless" target="_blank" rel="noopener" title="Sina" href="https://weibo.com/5539423521/profile"><i class="fab fa-weibo"></i></a></div></div></div><div class="card widget"><div class="card-content"><h3 class="menu-label">最新文章</h3><article class="media"><div class="media-content size-small"><p><time dateTime="2020-06-06T07:06:30.000Z">2020-06-06</time></p><p class="title is-6"><a class="link-muted" href="/2020/06/06/webpack-multi-config/">继续学习webpack，webpack的多入口，多配置文件等.</a></p><p class="is-uppercase"><i class="fas fa-folder-open has-text-grey"> </i><a class="link-muted" href="/categories/webpack/">webpack</a></p></div></article><article class="media"><div class="media-content size-small"><p><time dateTime="2020-05-30T10:34:00.000Z">2020-05-30</time></p><p class="title is-6"><a class="link-muted" href="/2020/05/30/StructOfData-DLinkList-TwoDirection/">数据结构 双向循环链表</a></p><p class="is-uppercase"><i class="fas fa-folder-open has-text-grey"> </i><a class="link-muted" href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></p></div></article><article class="media"><div class="media-content size-small"><p><time dateTime="2020-05-30T10:33:35.000Z">2020-05-30</time></p><p class="title is-6"><a class="link-muted" href="/2020/05/30/StructOfData-DLinkListRound/">数据结构 循环链表</a></p><p class="is-uppercase"><i class="fas fa-folder-open has-text-grey"> </i><a class="link-muted" href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></p></div></article><article class="media"><div class="media-content size-small"><p><time dateTime="2020-05-30T09:59:10.000Z">2020-05-30</time></p><p class="title is-6"><a class="link-muted" href="/2020/05/30/StructOfData-LinkList-Operation/">数据结构 单链表的基本操作</a></p><p class="is-uppercase"><i class="fas fa-folder-open has-text-grey"> </i><a class="link-muted" href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></p></div></article><article class="media"><div class="media-content size-small"><p><time dateTime="2020-05-30T07:25:03.000Z">2020-05-30</time></p><p class="title is-6"><a class="link-muted" href="/2020/05/30/StructOfData-SequenList-Operation/">数据结构 线性表的初始化及操作</a></p><p class="is-uppercase"><i class="fas fa-folder-open has-text-grey"> </i><a class="link-muted" href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></p></div></article></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">分类</h3><ul class="menu-list"><li><a class="level is-mobile is-marginless" href="/categories/Github/"><span class="level-start"><span class="level-item">Github</span></span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/JavaScript/"><span class="level-start"><span class="level-item">JavaScript</span></span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/Python/"><span class="level-start"><span class="level-item">Python</span></span><span class="level-end"><span class="level-item tag">2</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/Vue-js/"><span class="level-start"><span class="level-item">Vue.js</span></span><span class="level-end"><span class="level-item tag">20</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/git/"><span class="level-start"><span class="level-item">git</span></span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/node/"><span class="level-start"><span class="level-item">node</span></span><span class="level-end"><span class="level-item tag">6</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/webpack/"><span class="level-start"><span class="level-item">webpack</span></span><span class="level-end"><span class="level-item tag">6</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/web%E5%AD%A6%E4%B9%A0/"><span class="level-start"><span class="level-item">web学习</span></span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"><span class="level-start"><span class="level-item">数据结构</span></span><span class="level-end"><span class="level-item tag">4</span></span></a></li><li><a class="level is-mobile is-marginless" href="/categories/%E7%94%B5%E8%84%91%E7%9B%B8%E5%85%B3/"><span class="level-start"><span class="level-item">电脑相关</span></span><span class="level-end"><span class="level-item tag">3</span></span></a></li><a class="level is-mobile is-marginless" href="/categories/"><span class="level-start"><span class="level-item">查看全部&gt;&gt;</span></span></a></ul></div></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">归档</h3><ul class="menu-list"><li><a class="level is-mobile is-marginless" href="/archives/2020/06/"><span class="level-start"><span class="level-item">六月 2020</span></span><span class="level-end"><span class="level-item tag">1</span></span></a></li><li><a class="level is-mobile is-marginless" href="/archives/2020/05/"><span class="level-start"><span class="level-item">五月 2020</span></span><span class="level-end"><span class="level-item tag">13</span></span></a></li><li><a class="level is-mobile is-marginless" href="/archives/2020/04/"><span class="level-start"><span class="level-item">四月 2020</span></span><span class="level-end"><span class="level-item tag">9</span></span></a></li><li><a class="level is-mobile is-marginless" href="/archives/2020/03/"><span class="level-start"><span class="level-item">三月 2020</span></span><span class="level-end"><span class="level-item tag">10</span></span></a></li><li><a class="level is-mobile is-marginless" href="/archives/2020/02/"><span class="level-start"><span class="level-item">二月 2020</span></span><span class="level-end"><span class="level-item tag">12</span></span></a></li><a class="level is-mobile is-marginless" href="/archives/"><span class="level-start"><span class="level-item">查看全部&gt;&gt;</span></span></a></ul></div></div></div><div class="card widget"><div class="card-content"><div class="menu"><h3 class="menu-label">标签</h3><div class="field is-grouped is-grouped-multiline"><div class="control"><a class="tags has-addons" href="/tags/Vue/"><span class="tag">Vue</span><span class="tag is-grey-lightest">19</span></a></div><div class="control"><a class="tags has-addons" href="/tags/webpack/"><span class="tag">webpack</span><span class="tag is-grey-lightest">5</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"><span class="tag">数据结构</span><span class="tag is-grey-lightest">4</span></a></div><div class="control"><a class="tags has-addons" href="/tags/java/"><span class="tag">java</span><span class="tag is-grey-lightest">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/node/"><span class="tag">node</span><span class="tag is-grey-lightest">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%AC%94%E8%AE%B0/"><span class="tag">笔记</span><span class="tag is-grey-lightest">3</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Python-%E7%88%AC%E8%99%AB/"><span class="tag">Python,爬虫</span><span class="tag is-grey-lightest">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E9%A1%B9%E7%9B%AE/"><span class="tag">项目</span><span class="tag is-grey-lightest">2</span></a></div><div class="control"><a class="tags has-addons" href="/tags/CSS/"><span class="tag">CSS</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/ES6/"><span class="tag">ES6</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Github/"><span class="tag">Github</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Python/"><span class="tag">Python</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Vue%E7%AC%94%E8%AE%B0/"><span class="tag">Vue笔记</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/Windows%E6%8A%80%E5%B7%A7/"><span class="tag">Windows技巧</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/babel/"><span class="tag">babel</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/git/"><span class="tag">git</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E6%BF%80%E6%B4%BB/"><span class="tag">激活</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%94%B5%E8%84%91/"><span class="tag">电脑</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E7%AC%94%E8%AE%B0-Vue-js-Webpack/"><span class="tag">笔记, Vue.js, Webpack</span><span class="tag is-grey-lightest">1</span></a></div><div class="control"><a class="tags has-addons" href="/tags/%E8%B7%A8%E5%9F%9F/"><span class="tag">跨域</span><span class="tag is-grey-lightest">1</span></a></div></div><div class="field is-grouped is-grouped-multiline"><a class="tags has-addons" href="/tags/"><span class="tag">查看全部&gt;&gt;</span></a></div></div></div></div></div></div></div></section><footer class="footer"><div class="container"><div class="level"><div class="level-start"><a class="footer-logo is-block mb-2" href="/"><img src="https://cdn.jsdelivr.net/gh/uncledwyane/imageBed/img/logo.png" alt="Wb&#039;s blog" height="28"></a><p class="size-small"><span>&copy; 2020 Wb's blog</span>  Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> &amp; <a href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank">Icarus</a>,Modify by <a href="https://github.com/removeif/hexo-theme-amazing" target="_blank">removeif</a> <br></p></div><div class="level-end"><div class="field has-addons"><p class="control"><a class="button is-transparent is-large" target="_blank" rel="noopener" title="Creative Commons" href="https://creativecommons.org/"><i class="fab fa-creative-commons"></i></a></p><p class="control"><a class="button is-transparent is-large" target="_blank" rel="noopener" title="Attribution 4.0 International" href="https://creativecommons.org/licenses/by/4.0/"><i class="fab fa-creative-commons-by"></i></a></p><p class="control"><a class="button is-transparent is-large" target="_blank" rel="noopener" title="Download on GitHub" href="https://github.com/removeif"><i class="fab fa-github"></i></a></p></div></div></div></div></footer><script src="https://cdnjs.loli.net/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script><script>moment.locale("zh-CN");</script><script>var IcarusThemeSettings = {
            site: {
                url: 'https://hywb.xyz',
                external_link: {"enable":true,"exclude":[]}
            },
            article: {
                highlight: {
                    clipboard: true,
                    fold: 'unfolded'
                }
            }
        };</script><script src="https://cdnjs.loli.net/ajax/libs/clipboard.js/2.0.4/clipboard.min.js" defer></script><script src="/js/animation.js"></script><a id="back-to-top" title="回到顶端" href="javascript:;"><i class="fas fa-chevron-up"></i></a><script src="/js/back-to-top.js" defer></script><!--!--><script src="https://cdnjs.loli.net/ajax/libs/lightgallery/1.6.12/js/lightgallery-all.min.js" defer></script><script src="https://cdnjs.loli.net/ajax/libs/justifiedGallery/3.7.0/js/jquery.justifiedGallery.min.js" defer></script><!--!--><!--!--><!--!--><script src="/js/toc.js" defer></script><script src="/js/main.js" defer></script><script>$.getScript('/js/comment-issue-data.js',function(){loadIssueData('jEO65FCCVCAiARdU3RxjtOCJ-gzGzoHsz','1N2c9aedff0KFRrS6cJL6IHK','Bo','undefined',true);})</script><link rel="stylesheet" href="/css/insight.css"><div class="searchbox ins-search"><div class="searchbox-container ins-search-container"><div class="searchbox-input-wrapper"><input class="searchbox-input ins-search-input" type="text" placeholder="想要查找什么..."><span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span></div><div class="searchbox-result-wrapper ins-section-wrapper"><div class="ins-section-container"></div></div></div></div><script>(function (window) {
            var INSIGHT_CONFIG = {
                TRANSLATION: {
                    POSTS: '文章',
                    PAGES: '页面',
                    CATEGORIES: '分类',
                    TAGS: '标签',
                    UNTITLED: '(无标题)',
                },
                CONTENT_URL: '/content.json',
            };
            window.INSIGHT_CONFIG = INSIGHT_CONFIG;
        })(window);</script><script src="/js/insight.js" defer></script></body></html>